package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.Vo.MenuItemVo;
import com.zzyl.Vo.UserpageVo;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.LoginDto;
import com.zzyl.dto.UserAddDto;
import com.zzyl.dto.UserlistDto;
import com.zzyl.dto.UserpageDto;
import com.zzyl.entity.Resource;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.UserRoleMapp;
import com.zzyl.mapper.UserusMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.properties.SecurityConfigProperties;
import com.zzyl.service.ResourceService;
import com.zzyl.service.UserService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.UserVo;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.zzyl.constant.Constants.JWT_USERID;
import static com.zzyl.constant.Constants.JWT_USERNAME;
import static com.zzyl.constant.SuperConstant.*;
import static com.zzyl.constant.UserCacheConstant.USER_RESOURCE_LIST;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserusMapper userusMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapp userRoleMapp;

    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ResourceService resourceService;


    @Autowired
    private SecurityConfigProperties securityConfigProperties;

    /*
     * 分页查询
     * */
    @Override
    public PageResponse<UserpageVo> page(Integer pageNum, Integer pageSize, UserpageDto dto) {
        //开启分页
        PageHelper.startPage(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);

        // 单独处理下部门编号
        if (!StringUtils.isEmpty(dto.getDeptNo())) {
            dto.setDeptNo(NoProcessing.processString(dto.getDeptNo()));
        }

        Page<UserpageVo> page = userusMapper.page(dto);
        List<UserpageVo> result = page.getResult();
       /* if (!CollectionUtils.isEmpty(result)) {
            for (UserpageVo vo : result) {
                // 检查vo.getRoleIds()是否为空或null，并设置roleVoIds
                if (StringUtils.isEmpty(vo.getRoleIds())) {
                    vo.setRoleVoIds(new ArrayList<>());
                } else {
                    vo.setRoleVoIds(Arrays.asList(vo.getRoleIds().split(",")));
                }
                // 检查vo.getRoleNames()是否为空或null，并设置roleLabels
                if (vo.getRoleNames() == null || vo.getRoleNames().isEmpty()) {
                    vo.setRoleLabels(new ArrayList<>());
                } else {
                    vo.setRoleLabels(new ArrayList<>(vo.getRoleNames()));
                }*/
        if (!CollectionUtils.isEmpty(result)) {
            result.stream().forEach((vo) -> {
                vo.setRoleVoIds(StringUtils.isEmpty(vo.getRoleIds()) ? new ArrayList<>() : Arrays.asList(vo.getRoleIds().split(",")));
                vo.setRoleLabels(StringUtils.isEmpty(vo.getRoleNames()) ? new ArrayList<>() : Arrays.asList(vo.getRoleNames().split(",")));
            });
        }
        return PageResponse.of(page, UserpageVo.class);
    }


    @Override
    public void Add(UserAddDto dto) {
        //判断重复
        User user = userusMapper.selectByEmail(dto.getEmail());
        if (user != null) {
            throw new BaseException(BasicEnum.DATA_EXIST);
        }
        // 保存user
        User user1 = BeanUtil.copyProperties(dto, User.class);
        String hashpw = BCrypt.hashpw("123456");
        user1.setPassword(hashpw);
        user1.setUsername(dto.getEmail());
        userusMapper.insert(user1);
        // 保存角色
        if (!CollectionUtils.isEmpty(dto.getRoleVoId())) {
            List<UserRole> userRoles = dto.getRoleVoId().stream().map(r -> {
                UserRole ur = new UserRole();
                ur.setRoleId(Long.parseLong(r));
                ur.setUserId(user1.getId());
                ur.setDataState(DATA_STATE_0);
                return ur;
            }).collect(Collectors.toList());

            userRoleMapp.insertBatch(userRoles);
        }
    }

    /*
     * 删除
     * */
    @Override
    public void shanchu(Long id) {
        //判断禁用 启用不可删除
        User user = userRoleMapp.paiduan(id);
        if (Objects.equals(user.getDataState(), DATA_STATE_0)) {
            throw new BaseException(BasicEnum.ENABLED_CANNOT_DELETED);
        }

        //删除用户
        userRoleMapp.shanchu(id, Integer.parseInt(SuperConstant.DATA_STATE_1));
        //插入角色和用户关联表


    }

    /**
     * 用户列表
     */

    @Override
    public List<User> liebiao(UserlistDto dto) {
        List<User> user = userusMapper.liebiao(dto);
        return user;
    }

    /**
     * 启用禁用
     */

    @Override
    public void qiyongjinyong(Long id, Integer status) {
        userusMapper.qiyongjinyong(id, status);


    }

    /*
     * 修改
     * */
    @Override
    public void xiugai(UserAddDto dto) {
        //判断重复
        User user = userusMapper.selectByEmail(dto.getEmail());
        if (user != null) {
            throw new BaseException(BasicEnum.DATA_EXIST);
        }
        //更新uesr表
        User user1 = BeanUtil.copyProperties(dto, User.class);
        user1.setUsername(dto.getEmail());
        userusMapper.updateById(user1);
        //删除角色和用户关联表
        userRoleMapp.deleteByUserId(dto.getId());

        //插入角色和用户关联表
        if (!CollectionUtils.isEmpty(dto.getRoleVoId())) {
            List<UserRole> userRoles = dto.getRoleVoId().stream().map(r -> {
                UserRole ur = new UserRole();
                ur.setRoleId(Long.parseLong(r));
                ur.setUserId(dto.getId());
                ur.setDataState(DATA_STATE_0);
                return ur;
            }).collect(Collectors.toList());

            userRoleMapp.insertBatch(userRoles);
        }


    }


    /*
     * 删除
     * */
    @Override
    public void mima(Long userId) {
        String hashpw = BCrypt.hashpw("123456");
        userusMapper.mima(userId, hashpw);
    }

    @Override
    public UserVo longin(LoginDto dto) {
        // 根据用户名查库
        UserVo userVo = userusMapper.selectByName(dto.getUsername());
        // 判断用户是否存在
        if(userVo == null){
            // 如果不存在，return
            throw new BaseException(BasicEnum.DATA_NOT_EXIST);
        }
        // 如果存在， 判断状态是否禁用
        String dataState = userVo.getDataState();
        if(Objects.equals(dataState, DATA_STATE_1)){
            // 如果是禁用，return
            throw new BaseException(BasicEnum.USER_STATE_1);
        }
        // 如果不是禁用，校验密码，BCrypt
        String passwordDB = userVo.getPassword();
        if(!BCrypt.checkpw(dto.getPassword(), passwordDB)){
            // 如果密码错误，return
            throw new BaseException(BasicEnum.PASSWORD_ERROR);
        }
        // 查询用户的权限
        List<Resource> resourceList = resourceService.getByUserId(userVo.getId(),  null,null);
        // 获取白名单
        List<String> publicAccessUrls = securityConfigProperties.getPublicAccessUrls();
        Set<String> urlSet = new HashSet<>();
        if(!CollectionUtils.isEmpty(resourceList)){
            Set<String> urls = resourceList.stream().map(Resource::getLabel).filter(Objects::nonNull).collect(Collectors.toSet());
            urlSet.addAll(urls);
        }
        if(!CollectionUtils.isEmpty(publicAccessUrls)){
            urlSet.addAll(publicAccessUrls);
        }
        // 保存到redis
        redisTemplate.opsForSet().add(USER_RESOURCE_LIST + userVo.getId(), new ArrayList<>(urlSet).toArray(new String[0]));
        // 如果密码正确，生成token，return
        Map<String,Object> map = new HashMap<>();
        map.put(JWT_USERID,userVo.getId());
        map.put(JWT_USERNAME,dto.getUsername());
        userVo.setUserToken(JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(), jwtTokenManagerProperties.getTtl(),map));
        userVo.setPassword("");
        return userVo;
    }

    @Override
    public List<MenuItemVo> getMenuByUserId(Long mgtUserId) {
        List<Resource> menuList = resourceService.getByUserId(mgtUserId,DATA_STATE_0,SuperConstant.MENU);
        if(CollectionUtils.isEmpty(menuList)){
            return new ArrayList<>();

    }

    // 组织成tree结构

    // 把Resource转化成MenuItemVo
    List<MenuItemVo> menuItemVoList = new ArrayList<>();
    for (Resource resource : menuList) {
        MenuItemVo vo = BeanUtil.copyProperties(resource, MenuItemVo.class);
        vo.setName(resource.getResourceName());
        vo.setPath(resource.getRequestPath());
        vo.setRedirect("/"+resource.getResourceName());
        vo.setChildren(new ArrayList<>());
        vo.setMeta(new MenuItemVo.Meta(resource.getResourceName(),resource.getIcon()));
        menuItemVoList.add(vo);
    }
        // 构造根节点
        MenuItemVo root = new MenuItemVo();
        root.setResourceNo(ROOT_PARENT_ID);
        root.setChildren(new ArrayList<>());
        tree(root,menuItemVoList);
        return  root.getChildren();
}
    private void tree(MenuItemVo parent, List<MenuItemVo> menuItemVoList){
        for (MenuItemVo vo : menuItemVoList) {
            if (Objects.equals(vo.getResourceNo(),parent.getResourceNo())){
                parent.getChildren().add(vo);
                tree(vo,menuItemVoList);
            }
        }

    }
}









      /*  //查询用户 ，部门，职位
        Page<UserpageVo> page = userusMapper.page1(dto);
        List<UserpageVo> result =page.getResult();
        //单独处理角色
        if(!CollectionUtils.isEmpty(result)){
            //拿到所有的id用户
            List<Long>userIds=result.stream().map(UserpageVo::getId).collect(Collectors.toList());
            //根据用户ids 批量查用户的角色
            List<RoleWithUserId>roles=roleMapper.selectRoleListByUserIds(userIds);
            if (!CollectionUtils.isEmpty(roles)){
                //把角色的List转化成了map，key：userId，vaLue：用户的角色列表
                Map<Long,List<RoleWithUserId>>roleMap=roles.stream().collect(Collectors.groupingBy(RoleWithUserId::getUserId));

                for (UserpageVo vo : result) {
                    //根据用户ID 拿到所有角色
                    List<RoleWithUserId> roleWithUserIds = map.get(UserpageVo.getId());
                    if(!CollectionUtils.isEmpty(roleWithUserIds)){
                        UserpageVo.setRoleVoIds(roleWithUserIds.stream().map(RoleWithUserId::getRoleId).collect(Collectors.toList()));

                        UserpageVo.setRoleLabels(roleWithUserIds.stream().map(RoleWithUserId::getRoleName).collect(Collectors.toList()));
                    }
                }
            }*/
















